home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / allocate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-16  |  21.5 KB  |  756 lines

  1. /*
  2.  * @(#)allocate.c    1.4  3/2/88
  3.  */
  4. #include <stdio.h>
  5. #include "assert.h"
  6. #include "addresses.h"
  7. #include "nodes.h"
  8. #include "map.h"
  9. #include "sequence.h"
  10. #include "system.h"
  11. #include "semantics.h"
  12. #include "flags.h"
  13. #include "builtins.h"
  14. #include "evaluate.h"
  15. #include "opNames.h"
  16. #include "allocate.h"
  17. #include "trace.h"
  18. #include "option.h"
  19. #include "genutils.h"
  20.  
  21. /*
  22.  * This is the allocation pass of the compiler.  The basic purpose is to
  23.  * traverse the tree, deciding on the concrete type and implementation kind
  24.  * of each variable and constant (constants should be easy), to allocate
  25.  * space in the activation records and object data areas, and to determine
  26.  * the address of each thing.  In addition, since we are stupid about
  27.  * generating code, we also need to allocate the addresses of the temporaries
  28.  * used in expression evaluation, in particular, multiple assignments.
  29.  *
  30.  * The current algorithm for determining concrete type and implementation
  31.  * kind information is very simple.  Integers, Characters, Booleans, Real are
  32.  * Direct Builtins, Strings, Time and Conditions are
  33.  * Local Builtins, and everything else, including arrays and vectors, are
  34.  * Globals.
  35.  */
  36.  
  37. static void doChildren(), allocateSpaceInObject(), 
  38.         allocateSpaceInActivation();
  39.  
  40. static Map allocMap;
  41. Address nullAddress = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  42.  
  43. AllocationInfoPtr allocateAllocationInfo(p)
  44. NodePtr p;
  45. {
  46.   AllocationInfoPtr ap;
  47.   ap = (AllocationInfoPtr) Map_Lookup(allocMap, (int) p);
  48.   assert((int) ap == NIL || (int) ap == 1);
  49.   ap = (AllocationInfoPtr) calloc(sizeof(AllocationInfo), 1);
  50.   Map_Insert(allocMap, (int)p, (int) ap);
  51.   return(ap);
  52. }
  53.  
  54. AllocationInfoPtr fetchAllocationInfo(p)
  55. NodePtr p;
  56. {
  57.   AllocationInfoPtr ap;
  58.   ap = (AllocationInfoPtr) Map_Lookup(allocMap, (int) p);
  59.   assert((int) ap != NIL);
  60.   return(ap);
  61. }
  62.  
  63. typedef struct DeclInfo {
  64.   NodePtr        scope;
  65.   NodePtr        identList;
  66.   struct DeclInfo    *next;
  67. } DeclInfo, *DeclInfoPtr;
  68.  
  69. static DeclInfoPtr stack = NULL;
  70.  
  71. static void push(p)
  72. NodePtr p;
  73. {
  74.   register DeclInfoPtr t;
  75.   t = (DeclInfoPtr) malloc(sizeof(DeclInfo));
  76.   t->scope = p;
  77.   t->identList = NN;
  78.   t->next = stack;
  79.   stack = t;
  80. }
  81.  
  82. static void swap()
  83. {
  84.   DeclInfoPtr temp, temp2;
  85.   assert(stack != NULL);
  86.   assert(stack->next != NULL);
  87.   temp2 = stack->next->next;
  88.   temp = stack;
  89.   stack = stack->next;
  90.   temp->next = stack->next;
  91.   stack->next = temp;
  92.   assert(stack != NULL);
  93.   assert(stack->next != NULL);
  94.   assert(temp2 == stack->next->next);
  95. }
  96.  
  97. static void writeAddress(fp, a)
  98. FILE *fp;
  99. Address a;
  100. {
  101.   DD d;
  102.   d.kind = DD_Address;
  103.   d.value.address = a;
  104.   displayDD(fp, d, '\0');
  105. }
  106.  
  107. extern FILE *treeFile;
  108.  
  109. static void pop()
  110. {
  111.   register NodePtr p;
  112.   DeclInfoPtr this = stack;
  113.   Symbol st;
  114.   Tag tag;
  115.   stack = this->next;
  116.   tag = this->scope->tag;
  117.   if (tag == P_OBLIT) {
  118.     allocateSpaceInObject(this->scope, this->identList, FALSE);
  119.   } else if (tag == P_INITDEF) {
  120.     assert(stack != NULL);
  121.     assert(stack->scope != NULL);
  122.     assert(stack->scope->tag == P_OBLIT);
  123.     allocateSpaceInActivation((NodePtr)((int)(stack->scope)+1),
  124.       this->identList, FALSE);
  125.   } else if (tag == P_OPDEF || tag == P_OPSIG ||
  126.          tag == P_PROCESSDEF || tag == P_RECOVERYDEF) {
  127.     allocateSpaceInActivation(this->scope, this->identList, FALSE);
  128.   } else if (tag == P_COMP) {
  129.     allocateSpaceInObject(this->scope, this->identList, FALSE);
  130.   } else if (tag == P_ATLIT) {
  131.     assert(Sequence_Length(this->identList) == 0);
  132.   } else {
  133.     assert(FALSE);
  134.   }
  135.  
  136.   IFTRACE(allocate, 1) {
  137.     fprintf(stdout, "%s ", tagNames[(int)this->scope->tag]);
  138.     if (this->scope->tag == P_OPDEF) {
  139.       fprintf(stdout, "%s ", 
  140.     ON_Name(this->scope->b.opdef.sig->b.opsig.name->b.opname.id));
  141.     } else if (this->scope->tag == P_OPSIG) {
  142.       fprintf(stdout, "%s ", ON_Name(this->scope->b.opsig.name->b.opname.id));
  143.     } else if (this->scope->tag == P_OBLIT) {
  144.       st = ST_Fetch(this->scope->b.oblit.name->b.symdef.symbol);
  145.       fprintf(stdout, "%s ", ST_SymbolName(st));
  146.     }
  147.     if (Sequence_Length(this->identList) == 0) {
  148.       fprintf(stdout, "defines nothing");
  149.     } else {
  150.       fprintf(stdout, "defines:\n  ");
  151.       Sequence_For(p, this->identList)
  152.     fprintf(stdout, "%s ", ST_SymbolName(ST_Fetch(p->b.symref.symbol)));
  153.     writeAddress(stdout, ST_Fetch(p->b.symdef.symbol)->v.address);
  154.     fprintf(stdout, ", ");
  155.       Sequence_Next
  156.     }
  157.     fprintf(stdout, "\n");
  158.   }
  159.   free((char *)this);
  160. }
  161.  
  162. void allocate();
  163.  
  164. void initializeAllocate()
  165. {
  166. }
  167.  
  168. void ATCTToSizeAndKind(at, ct, isAttached, size, ak)
  169. NodePtr at, ct;
  170. Boolean isAttached;
  171. int *size;
  172. AllocateKind *ak;
  173. {
  174.   OID atOID, ctOID;
  175.   at = figureOutAT(at);
  176.   atOID = at->b.atlit.id;
  177.   if (atOID == OIDOfBuiltin(B_INSTAT, BOOLEANINDEX) ||
  178.       atOID == OIDOfBuiltin(B_INSTAT, CHARACTERINDEX)) {
  179.     *ak = AK_Boring; *size = 1;
  180.   } else if (atOID == OIDOfBuiltin(B_INSTAT, INTEGERINDEX) ||
  181.          atOID == OIDOfBuiltin(B_INSTAT, REALINDEX)) {
  182.     *ak = AK_Boring; *size = 4;
  183.   } else if (atOID == OIDOfBuiltin(B_INSTAT, STRINGINDEX) ||
  184.          atOID == OIDOfBuiltin(B_INSTAT, TIMEINDEX)) {
  185.     *ak = AK_Local ; *size = 4;
  186.   } else if (atOID == OIDOfBuiltin(B_INSTAT, CONDITIONINDEX) ||
  187.          atOID == OIDOfBuiltin(B_INSTAT, NODEINDEX)) {
  188.     if (isAttached) *ak = AK_AttachedLocal; else *ak = AK_Local;
  189.     *size = 4;
  190.   } else {
  191.     if (ct == NULL && at->b.atlit.f.cannotBeConformedTo) {
  192.       extern NodePtr OTLookup();
  193.       assert(at->b.atlit.codeOID != NULL);
  194.       ct = OTLookup(at->b.atlit.codeOID);
  195.     }
  196.     if (ct != NULL) {
  197.       ctOID = getID(ct);
  198.       if (ctOID == OIDOfBuiltin(B_INSTCT, BOOLEANINDEX) ||
  199.       ctOID == OIDOfBuiltin(B_INSTCT, CHARACTERINDEX)) {
  200.     *ak = AK_Boring; *size = 1;
  201.       } else if (ctOID == OIDOfBuiltin(B_INSTCT, INTEGERINDEX) ||
  202.          ctOID == OIDOfBuiltin(B_INSTCT, REALINDEX)) {
  203.     *ak = AK_Boring; *size = 4;
  204.       } else if (ctOID == OIDOfBuiltin(B_INSTCT, STRINGINDEX) ||
  205.          ctOID == OIDOfBuiltin(B_INSTCT, TIMEINDEX)) {
  206.     *ak = AK_Local ; *size = 4;
  207.       } else if (ctOID == OIDOfBuiltin(B_INSTCT, CONDITIONINDEX) ||
  208.          ctOID == OIDOfBuiltin(B_INSTCT, NODEINDEX)) {
  209.     if (isAttached) *ak = AK_AttachedLocal; else *ak = AK_Local;
  210.     *size = 4; /* local => we know CT */
  211.       } else {
  212.     if (isAttached) *ak = AK_AttachedLocal; else *ak = AK_Local;
  213.     *size = 4; /* local => we know CT */
  214.       }
  215.     } else if (isAttached) {
  216.       *ak = AK_AttachedGlobal; *size = 8;
  217.     } else {
  218.       *ak = AK_Global; *size = 8;
  219.     }
  220.   }
  221. }
  222.  
  223. void figureSizeAndKind(sym, size, ak)
  224. Symbol sym;
  225. int *size;
  226. AllocateKind *ak;
  227. {
  228.   ATCTToSizeAndKind(sym->value.ATinfo, sym->value.CTinfo, sym->isAttached,
  229.     size, ak);
  230.   if (*size == 1) *size = 4;
  231. }
  232.  
  233. static void allocateSpaceInObject(scope, identList, secondTry)
  234. NodePtr scope, identList;
  235. Boolean secondTry;
  236. {
  237.   int sizes[NUMKINDS], offsets[NUMKINDS];
  238.   int size, i, offset;
  239.   AllocateKind ak;
  240.   register NodePtr p;
  241.   register Symbol sym;
  242.   AllocationInfoPtr ap;
  243.   int firstinstanceoffset = firstInstanceOffset;
  244.  
  245.   assert(!secondTry);
  246.   for (i = 0; i < NUMKINDS; i++) {
  247.     sizes  [i] = 0;
  248.     offsets[i] = 0;
  249.   }
  250.   /*
  251.    * Allocate the monitor lock.
  252.    */
  253.   if (scope->tag == P_OBLIT && scope->b.oblit.monitor != NN && 
  254.       ! scope->b.oblit.monitor->b.monitor.mayBeElided) {
  255.     sizes[AK_Monitor] += 8; offsets[AK_Monitor] = sizes[AK_Monitor];
  256.   }
  257.   if (scope->tag == P_OBLIT && scope->b.oblit.f.immutable) {
  258.     /* we allocate space for the ownOID field */
  259.     firstinstanceoffset += sizeof(OID);
  260.   }
  261.   Sequence_For(p, identList)
  262.     assert(p->tag == P_SYMDEF);
  263.     sym = ST_Fetch(p->b.symdef.symbol);
  264.     figureSizeAndKind(sym, &size, &ak);
  265.     sizes  [ak] += size;
  266.   Sequence_Next
  267.   Sequence_For(p, identList)
  268.     assert(p->tag == P_SYMDEF);
  269.     sym = ST_Fetch(p->b.symdef.symbol);
  270.     figureSizeAndKind(sym, &size, &ak);
  271.     sym->v.address = nullAddress;
  272.     sym->v.address.base = Global;
  273.     offset = firstinstanceoffset;
  274.     for (i = ak+1; i < NUMKINDS; i++) {
  275.       offset += sizes[i];
  276.     }
  277.     offset += offsets[ak];
  278.     sym->v.address.offset = offset;
  279.     offsets[ak] += size;
  280.   Sequence_Next
  281.   for (i = 0; i < NUMKINDS; i++) {
  282.     assert(offsets[i] == sizes[i]);
  283.   }
  284.   ap = allocateAllocationInfo(scope);
  285.   ap->isDataArea = TRUE;
  286.   ap->isActivation = FALSE;
  287.   ap->scope = scope;
  288.   ap->identList = identList;
  289.   ap->parameterSize = 0;
  290.   ap->resultSize = 0;
  291.   ap->boringSize = sizes[AK_Boring];
  292.   ap->localSize = sizes[AK_Local];
  293.   ap->attachedLocalSize = sizes[AK_AttachedLocal];
  294.   ap->globalSize = sizes[AK_Global];
  295.   ap->attachedGlobalSize = sizes[AK_AttachedGlobal];
  296.   ap->monitorSize = sizes[AK_Monitor];
  297.   ap->invokeQueueSize = sizes[AK_InvokeQueue];
  298. }
  299.  
  300. static void allocateSpaceInActivation(scope, identList, secondTry)
  301. NodePtr scope, identList;
  302. Boolean secondTry;
  303. {
  304.   int resultSize = 0, resultOffset = 0,
  305.       parameterSize = 0, parameterOffset = 0,
  306.       sizes[NUMKINDS], offsets[NUMKINDS], 
  307.       assignToRegs[NUMKINDS], nextReg[NUMKINDS];
  308.   register NodePtr p;
  309.   register Symbol sym;
  310.   NodePtr paramList = NULL, resultList = NULL;
  311.   AllocationInfoPtr ap;
  312.   register int i, whichReg;
  313.   int size, offset, nAvailable, nextFreeReg;
  314. #ifdef sun
  315.   int nAvailableAddress, nAvailableData;
  316.   int nextFreeRegAddress, nextFreeRegData;
  317. #endif
  318.   AllocateKind ak;
  319.   RAInfo regs[NALLOCATABLE];
  320.  
  321.   for (i = 0; i < NUMKINDS; i++) {
  322.     sizes  [i] = 0;    assignToRegs[i] = 0;
  323.     offsets[i] = 0;    nextReg[i] = 0;    
  324.   }
  325.   if (! secondTry) {
  326.     for (i = 0; i < NALLOCATABLE; i++) {
  327.       regs[i].isAllocated = FALSE;
  328.     }
  329.     /*
  330.      * TODO:  When I know how to get rid of the InvokeQueue, I can change this.
  331.      */
  332.     sizes[AK_InvokeQueue] = sizeof(InvokeQueue);
  333.     offsets[AK_InvokeQueue] = sizes[AK_InvokeQueue];
  334.     
  335.     Sequence_For(p, identList)
  336.       assert(p->tag == P_SYMDEF ||
  337.          p->tag == P_SYMREF);
  338.       sym = ST_Fetch(p->b.symdef.symbol);
  339.       switch (sym->itsKind) {
  340.     case ST_Param:
  341.       parameterSize += 8;
  342.       Sequence_Add(¶mList, p);
  343.       break;
  344.     case ST_Result:
  345.       resultSize += 8;
  346.       Sequence_Add(&resultList, p);
  347.       break;
  348.     case ST_Var:
  349.     case ST_Const:
  350.       figureSizeAndKind(sym, &size, &ak);
  351.       sizes  [ak] += size;
  352.       break;
  353.     default:
  354.       assert(FALSE);
  355.       break;
  356.       }
  357.     Sequence_Next
  358.     /*
  359.      * Decide which variables go in the registers.  We need to adjust the
  360.      * required sizes of the various storage classes.  For now, we will 
  361.      * just put locals, then data, then globals into the available registers.
  362.      */
  363. #   define MIN(A,B) ((A) < (B) ? (A) : (B))
  364.  
  365.     IFOPTION(allocateregisters, 1) {
  366. #ifdef vax
  367.       nAvailable = NALLOCATABLE * sizeof(int);
  368.       nextFreeReg = MINALLOCATABLE;
  369. #endif
  370. #ifdef sun
  371.       nAvailableAddress = 2 * sizeof(int);
  372.       nAvailableData = (NALLOCATABLE-2) * sizeof(int);
  373.       nextFreeRegAddress = MINALLOCATABLE;
  374.       nextFreeRegData = MINALLOCATABLE + 2;
  375.       nAvailable = nAvailableAddress;
  376.       nextFreeReg = nextFreeRegAddress;
  377. #endif
  378.       assignToRegs[AK_Local] = MIN(nAvailable, sizes[AK_Local]) / sizeof(int);
  379.       sizes[AK_Local] -= assignToRegs[AK_Local] * sizeof(int);
  380.       nextReg[AK_Local] = nextFreeReg;
  381.       nAvailable -= assignToRegs[AK_Local] * sizeof(int);
  382.       nextFreeReg += assignToRegs[AK_Local];
  383.  
  384.       assignToRegs[AK_AttachedLocal] = MIN(nAvailable, sizes[AK_AttachedLocal]) / sizeof(int);
  385.       sizes[AK_AttachedLocal] -= assignToRegs[AK_AttachedLocal] * sizeof(int);
  386.       nextReg[AK_AttachedLocal] = nextFreeReg;
  387.       nAvailable -= assignToRegs[AK_AttachedLocal] * sizeof(int);
  388.       nextFreeReg += assignToRegs[AK_AttachedLocal];
  389. #ifdef sun
  390.       nAvailableAddress = nAvailable;
  391.       nextFreeRegAddress = nextFreeReg;
  392.       nAvailable = nAvailableData;
  393.       nextFreeReg = nextFreeRegData;
  394. #endif
  395.       assignToRegs[AK_Boring] = MIN(nAvailable, sizes[AK_Boring]) / sizeof(int);
  396.       sizes[AK_Boring] -= assignToRegs[AK_Boring] * sizeof(int);
  397.       nextReg[AK_Boring] = nextFreeReg;
  398.       nAvailable -= assignToRegs[AK_Boring] * sizeof(int);
  399.       nextFreeReg += assignToRegs[AK_Boring];
  400. #ifdef sun
  401.       nAvailableData = nAvailable;
  402.       nextFreeRegData = nextFreeReg;
  403.       nAvailable = nAvailableAddress;
  404.       nextFreeReg = nextFreeRegAddress;
  405. #endif
  406.       assignToRegs[AK_Global] = MIN(nAvailable, sizes[AK_Global])
  407.     / ( 2 * sizeof(int));
  408.       sizes[AK_Global] -= assignToRegs[AK_Global] * 8;
  409.       nextReg[AK_Global] = nextFreeReg;
  410.       nAvailable -= assignToRegs[AK_Global] * 8;
  411.       nextFreeReg += assignToRegs[AK_Global];
  412.  
  413.       assignToRegs[AK_AttachedGlobal] = MIN(nAvailable, sizes[AK_AttachedGlobal])
  414.     / ( 2 * sizeof(int));
  415.       sizes[AK_AttachedGlobal] -= assignToRegs[AK_AttachedGlobal] * 8;
  416.       nextReg[AK_AttachedGlobal] = nextFreeReg;
  417.       nAvailable -= assignToRegs[AK_AttachedGlobal] * 8;
  418.       nextFreeReg += assignToRegs[AK_AttachedGlobal];
  419. #ifdef sun
  420.       nAvailableAddress = nAvailable;
  421.       nextFreeRegAddress = nextFreeReg;
  422. #endif
  423.     }
  424.   } else {
  425.     ap = fetchAllocationInfo(scope);
  426.     for (i = 0 ; i < NALLOCATABLE; i++) {
  427.       regs[i] = ap->regs[i];
  428.     }
  429.     sizes[AK_AttachedGlobal] = ap->attachedGlobalSize;
  430.     sizes[AK_Global] = ap->globalSize;
  431.     sizes[AK_AttachedLocal] = ap->attachedLocalSize;
  432.     sizes[AK_Local] = ap->localSize;
  433.     sizes[AK_Boring] = ap->boringSize;
  434.     sizes[AK_Monitor] = ap->monitorSize;
  435.     sizes[AK_InvokeQueue] = ap->invokeQueueSize;
  436.     parameterSize = ap->parameterSize;
  437.     resultSize = ap->resultSize;
  438.   }
  439.   Sequence_For(p, identList)
  440.     assert(p->tag == P_SYMDEF ||
  441.        p->tag == P_SYMREF);
  442.     sym = ST_Fetch(p->b.symdef.symbol);
  443.     switch (sym->itsKind) {
  444.       case ST_Param:
  445.     parameterOffset += 8;
  446.     offset = firstParameterOffset + parameterSize - parameterOffset;
  447.     if (secondTry) {
  448.       assert(sym->v.address.offset == offset);
  449.     } else {
  450.       sym->v.address = nullAddress;
  451.       sym->v.address.base = Local;
  452.       sym->v.address.offset = offset;
  453.     }
  454.     break;
  455.       case ST_Result:
  456.     resultOffset += 8;
  457.     offset = 
  458.       firstParameterOffset + parameterSize + resultSize - resultOffset;
  459.     if (secondTry) {
  460.       assert(sym->v.address.offset == offset);
  461.     } else {
  462.       sym->v.address = nullAddress;
  463.       sym->v.address.base = Local;
  464.       sym->v.address.offset = offset;
  465.     }
  466.     break;
  467.       case ST_Var:
  468.       case ST_Const:
  469.     figureSizeAndKind(sym, &size, &ak);
  470.     if (secondTry && sym->v.address.base == Register) {
  471.       /* do nothing - all done */
  472.     } else if (!secondTry && OPTION(allocateregisters, 1) && 
  473.         assignToRegs[ak] > 0) {
  474.       /* assign it to a register */
  475.       sym->v.address = nullAddress;
  476.       sym->v.address.base = Register;
  477.       sym->v.address.offset = nextReg[ak];
  478.       whichReg = sym->v.address.offset - MINALLOCATABLE;
  479.       regs[whichReg].isAllocated = TRUE;
  480.       regs[whichReg].isAttached = 
  481.         (ak == AK_AttachedLocal || ak == AK_AttachedGlobal);
  482.       regs[whichReg].itsKind = ak;
  483.       assignToRegs[ak] --;
  484.       nextReg[ak] ++;
  485.       if (ak == AK_Global || ak == AK_AttachedGlobal) {
  486.         /* do the next register, too */
  487.         regs[whichReg+1].isAllocated = TRUE;
  488.         regs[whichReg+1].isAttached = ak == AK_AttachedGlobal;
  489.         regs[whichReg+1].itsKind = ak;
  490.         nextReg[ak] ++;
  491.       }
  492.     } else {
  493.       offset = firstLocalOffset;
  494.       for (i = ak+1; i < NUMKINDS; i++) {
  495.         offset += sizes[i];
  496.       }
  497.       /*
  498.        * Note that on locals, since the stack grows backwards we increment
  499.        * the offset before we take the address of the thing.
  500.        */
  501.       offsets[ak] += size;
  502.       offset += offsets[ak];
  503.       if (secondTry && sym->v.address.offset != -offset) { 
  504.         TRACE3(allocate, 1, "%s changed from %d to %d", ST_SymbolName(sym),
  505.           sym->v.address.offset, -offset);
  506.       }
  507.       sym->v.address = nullAddress;
  508.       sym->v.address.base = Local;
  509.       sym->v.address.offset = - offset;
  510.     }
  511.     break;
  512.       default:
  513.     assert(FALSE);
  514.     break;
  515.     }
  516.   Sequence_Next
  517.   assert(parameterOffset == parameterSize);
  518.   assert(resultOffset == resultSize);
  519.   if (!secondTry) {
  520.     for (i = 0; i < NUMKINDS; i++) {
  521.       assert(offsets[i] == sizes[i]);
  522.     }
  523.     ap = allocateAllocationInfo(scope);
  524.     ap->isDataArea = FALSE;
  525.     ap->isActivation = TRUE;
  526.     ap->scope = scope;
  527.     ap->identList = identList;
  528.     ap->parameterSize = parameterSize;
  529.     ap->resultSize = resultSize;
  530.     ap->attachedGlobalSize = sizes[AK_AttachedGlobal];
  531.     ap->globalSize = sizes[AK_Global];
  532.     ap->attachedLocalSize = sizes[AK_AttachedLocal];
  533.     ap->localSize = sizes[AK_Local];
  534.     ap->boringSize = sizes[AK_Boring];
  535.     ap->monitorSize = sizes[AK_Monitor];
  536.     ap->invokeQueueSize = sizes[AK_InvokeQueue];
  537.     ap->paramList = paramList;
  538.     ap->resultList = resultList;
  539.     for (i = 0; i < NALLOCATABLE; i++) 
  540.       ap->regs[i] = regs[i];
  541.   }
  542. }
  543.  
  544. #define doChildren(p) {\
  545.   Sequence_For(child, p)\
  546.     if (child != NULL) allocate(child);\
  547.   Sequence_Next\
  548. }
  549.  
  550.  
  551. #define ISANABSTRACTTYPEID(X) \
  552.     ((X) == OIDOfBuiltin(B_INSTAT, ABSTRACTTYPEINDEX) || \
  553.      (X) == OIDOfBuiltin(B_INSTAT, SIGNATUREINDEX))
  554.  
  555. Boolean isARealImport(st, gen)
  556. register Symbol st;
  557. Boolean gen;
  558. {
  559. #undef PASSABSTRACTTYPES
  560. #ifdef PASSABSTRACTTYPES
  561.   register NodePtr at;
  562.   Boolean result;
  563.   if (! st->isManifest) return(TRUE);
  564.   at = figureOutAT(st->value.ATinfo);
  565.   assert(at->tag == P_ATLIT);
  566.   if (at->b.atlit.f.writeSeparately) return(FALSE);
  567.   result = ISANABSTRACTTYPEID(at->b.atlit.id);
  568.   return(! result);
  569. #else
  570.   if (gen) {
  571.     return(! st->isManifest);
  572.   } else {
  573.     return(st->value.value == NN);
  574.   }
  575. #endif
  576. }
  577.  
  578. static Boolean doneFirstObject;
  579.  
  580. void doAllocate(p, finalPass)
  581. NodePtr p;
  582. Boolean finalPass;
  583. {
  584.   NodePtr scope;
  585.   AllocationInfoPtr aip;
  586.   if (!finalPass) {
  587.     if (allocMap != (Map) NULL) Map_Destroy(allocMap);
  588.     allocMap = Map_Create();
  589.     doneFirstObject = FALSE;
  590.     allocate(p);
  591.   } else {
  592.     Map_For(allocMap, scope, aip)
  593.       if (! aip->isActivation) continue;
  594.       /* redo the allocation to fix the temporary stuff */
  595.       allocateSpaceInActivation(scope, aip->identList, TRUE);
  596.       IFTRACE(allocate, 1) {
  597.     fprintf(stdout, "%s ", tagNames[(int)aip->scope->tag]);
  598.     if (aip->scope->tag == P_OPDEF) {
  599.       fprintf(stdout, "%s ", 
  600.         ON_Name(aip->scope->b.opdef.sig->b.opsig.name->b.opname.id));
  601.     } else if (aip->scope->tag == P_OPSIG) {
  602.       fprintf(stdout, "%s ", ON_Name(aip->scope->b.opsig.name->b.opname.id));
  603.     }
  604.  
  605.     if (Sequence_Length(aip->identList) == 0) {
  606.       fprintf(stdout, "defines nothing");
  607.     } else {
  608.       fprintf(stdout, "defines:\n  ");
  609.       Sequence_For(p, aip->identList)
  610.         fprintf(stdout, "%s ", ST_SymbolName(ST_Fetch(p->b.symref.symbol)));
  611.         writeAddress(stdout, ST_Fetch(p->b.symdef.symbol)->v.address);
  612.         fprintf(stdout, ", ");
  613.       Sequence_Next
  614.     }
  615.     fprintf(stdout, "\n");
  616.       }
  617.     Map_Next
  618.   }
  619. }
  620.  
  621. Boolean isAManifestConstant(sym)
  622. Symbol sym;
  623. {
  624.   if (sym->isManifest) {
  625.     if (! Zflag) return(TRUE);
  626.     if (sym->value.value->tag != P_OBLIT) return(TRUE);
  627.     if (sym->value.value->b.oblit.f.immutable) return(TRUE);
  628.   }
  629.   return(FALSE);
  630. }
  631.  
  632. void allocate(p)
  633. NodePtr p;
  634. {
  635.   NodePtr setqs, q, r, s, phoneyInitially;
  636.   Symbol sym, paramsym;
  637.   register NodePtr child;
  638.  
  639.   if ((int) p <= 0x200) return;
  640.  
  641.   switch (p->tag) {
  642.     case P_OBLIT:
  643.       if (doneFirstObject) return;
  644.       doneFirstObject = TRUE;
  645.       /*
  646.        * We push a phoney initially, and when we hit initially it should be
  647.        * there, under the object record.  When we get to the initially we 
  648.        * will have to find this one.
  649.        */
  650.       phoneyInitially = Construct(P_INITDEF, 2, NULL, NULL);
  651.       push(p);
  652.       push(phoneyInitially);
  653.       setqs = p->b.oblit.setq;
  654.       Sequence_For(q, setqs)
  655.     /*
  656.      * For each import that is a real import, we declare space as a parameter 
  657.      * for the initially.  If the import is used outside of the initially, then
  658.      * we also allocate space for it in the object itself.  The initially code 
  659.      * will assign the parameter to the newly allocated space.
  660.      */
  661.     assert(q->tag == P_SETQ);
  662.     r = q->b.setq.inner;
  663.     assert(r->tag == P_SYMDEF);
  664.     sym = ST_Fetch(r->b.symref.symbol);
  665.     if (isARealImport(sym, TRUE)) {
  666.       /*
  667.        * This is a real import.
  668.        */
  669.       assert(sym->isImport);
  670.       s = Construct(P_SYMDEF, 0);
  671.       s->b.symdef.ident = r->b.symref.ident;
  672.       s->b.symdef.symbol = ST_Create(p, s->b.symdef.ident);
  673.       q->b.setq.param = s;
  674.       paramsym = ST_Fetch(s->b.symdef.symbol);
  675.       *paramsym = *sym;
  676.       paramsym->itsKind = ST_Param;
  677.       Sequence_Add(&stack->identList, s);
  678.       if (sym->usedOutsideInitially)
  679.         Sequence_Add(&stack->next->identList, q->b.setq.inner);
  680.     }
  681.       Sequence_Next
  682.       swap();
  683.       /* This is a do children, but don't do my own name. */
  684.       Sequence_For(child, p)
  685.     if (child != NULL && child != p->b.oblit.name) allocate(child);
  686.       Sequence_Next
  687.       assert(stack->scope->tag == P_OBLIT);
  688.       if (stack->next != NULL && stack->next->scope == phoneyInitially) {
  689.     swap();
  690.     pop();
  691.       }
  692.       pop();
  693.       break;
  694.     case P_COMP:
  695.       push(p);
  696.       doneFirstObject = TRUE;
  697.       doChildren(p);
  698.       pop();
  699.       break;
  700.     case P_PARAM:
  701.       assert(p->b.param.move == p->b.param.sym->b.symdef.symbol->isMove);
  702.       assert(p->b.param.isAttached == p->b.param.sym->b.symdef.symbol->isAttached);
  703.     case P_VARDECL:
  704.       doChildren(p);
  705.       break;
  706.     case P_CONSTDECL:
  707.       sym = p->b.constdecl.sym->b.symdef.symbol;
  708.       if (isAManifestConstant(sym)) return;
  709.       doChildren(p);
  710.       break;
  711.     case P_PROCESSDEF:
  712.     case P_RECOVERYDEF:
  713.     case P_OPDEF:
  714.       push(p);
  715.       doChildren(p);
  716.       pop();
  717.       break;
  718.     case P_ATLIT:
  719.       if (doneFirstObject) return;
  720.       doneFirstObject = TRUE;
  721.       push(p);
  722.       q = p->b.atlit.ops;
  723.       /* q is a sequence of operation signatures. */
  724.       Sequence_For(s, q)
  725.     if (Map_Lookup(allocMap, (int)s) == NIL) {
  726.       push(s);
  727.       allocate(s);
  728.       pop();
  729.     }
  730.       Sequence_Next
  731.       pop();
  732.       break;
  733.     case P_INITDEF:
  734.       /*
  735.        * We cheated before, now we reverse the order of the two top ones, and
  736.        * continue.
  737.        */
  738.       swap();
  739.       assert(stack->scope->tag == P_INITDEF);
  740.       stack->scope = p;
  741.       doChildren(p);
  742.       pop();
  743.       break;
  744.     case P_SYMDEF:
  745.       Sequence_Add(&stack->identList, p);
  746.       break;
  747.     case P_GLOBALREF:
  748.       break;
  749.     case P_SETQ:
  750.       break;
  751.     default:
  752.       doChildren(p);
  753.       break;
  754.   }
  755. }
  756.